package com.mediaideas.videoengine.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.mediaideas.videoengine.AudioMixerParams;
import com.mediaideas.videoengine.constants.AppConstants;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by Jonathan Kranz on 2016/3/10.
 */
public class FileUtils {
    public static final int MEDIA_TYPE_AUDIO = 0X0000;
    public static final int MEDIA_TYPE_IMAGE = 0X0001;
    public static final int MEDIA_TYPE_VIDEO = 0X0002;
    private static final String TAG = "FileUtils";

    public static String getXYJDir(Context context) throws XYJException {
        String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + AppConstants.APP_DIR_NAME;
        File dir = new File(dirPath);
        if (dir.exists() && !dir.isDirectory())
            dir.delete();

        if (!dir.exists()) {
            if (dir.mkdirs() || dir.isDirectory())
                return dirPath;
            else {
                // 重试一次
                if (dir.mkdirs() || dir.isDirectory())
                    return dirPath;
                else {
                    Log.e(TAG, "create XiYouJi folder failed");
                    throw new XYJException("create XiYouJi folder failed");
                }
            }
        }
        return dirPath;
    }

    public static void mkdir(String dirPath) {
        try {
            File dir = new File(dirPath);
            if (dir.exists() && dir.isFile()) {
                dir.delete();
            }

            if (!dir.isDirectory()) {
                dir.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean deleteFiles(List<String> filePaths) {
        if (filePaths == null || filePaths.size() == 0) {
            return false;
        }
        for (String filePath : filePaths) {
            if (FileUtils.isFileExists(filePath)) {
                FileUtils.deleteFile(filePath);
            }
        }
        return true;
    }

    /**
     * 删除目录下的文件(没有子文件夹的情况)
     *
     * @param filePath
     * @return
     */
    public static boolean deleteDir(String filePath) {
        if (filePath == null) {
            return false;
        }
        File file = new File(filePath);
        if (!file.isDirectory() || !file.exists()) {
            return false;
        }
        File[] files = file.listFiles();
        for (File tmpFile : files) {
            tmpFile.delete();
        }
        return file.delete();
    }

    /**
     * 返回目录下的文件
     *
     * @param dirPath
     * @return
     */
    public static File[] getFileFromDir(String dirPath) {
        if (dirPath == null)
            return new File[]{};
        File file = new File(dirPath);
        if (!file.isDirectory() || !file.exists()) {
            return new File[]{};
        }
        return file.listFiles();
    }

    public static boolean deleteFile(String path) {
        try {
            if (path == null) {
                return false;
            }
            File file = new File(path);
            if (file.exists()) {
                if (!file.delete())
                    return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    /**
     * 文件是否存在
     *
     * @param path
     * @return
     */
    public static boolean isFileExists(String path) {
        if (path == null)
            return false;
        File f = new File(path);
        return f.exists();
    }

    /**
     * 文件Uri转换为文件路径
     *
     * @param uri
     * @return
     */
    public static String fileUriToPath(Uri uri) {
        if (uri == null) {
            return null;
        }
        return Uri.decode(uri.getEncodedPath());
    }

    /**
     * 文件路径转换为文件uri
     *
     * @param path
     * @return
     */
    public static Uri filePathToUri(String path) {
        return Uri.fromFile(new File(path));
    }

    public static boolean equalsUri(Uri uri1, Uri uri2) {
        if (uri1 == null || uri2 == null) {
            return false;
        }
        return TextUtils.equals(uri1.toString(), uri2.toString());
    }

    public static String getLogFileFolder(Context context) {
        String dirPath = null;
        try {
            dirPath = getXYJDir(context) + AppConstants.FILE_SEPARATOR + AppConstants.APP_LOG_DIR_NAME;
            FileUtils.mkdir(dirPath);
            return dirPath;
        } catch (XYJException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * /storage/emulated/0/XiYouJi/sound/，没有则创建
     *
     * @param context
     * @return
     */
    public static String getSoundFileFolder(Context context) {
        String dirPath = null;
        try {
            dirPath = getXYJDir(context) + AppConstants.FILE_SEPARATOR + AppConstants.APP_SOUND_DIR_NAME;
            FileUtils.mkdir(dirPath);
            return dirPath;
        } catch (XYJException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取音频存放的文件 /sdcard/XiyouJI/sound/Record_1213131434.aac
     *
     * @param context
     * @return
     */
    public static String getNextSoundFileName(Context context) {
        return getSoundFileFolder(context) + File.separator + "Record_" + System.currentTimeMillis() + AudioMixerParams.AUDIO_SUFFIX_AAC;
    }

    /**
     * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
     * is persistent and available to other applications like gallery.
     *
     * @param context
     * @return A file object pointing to the newly created file.
     */
    public static File getAudioFile(Context context, String prefix) {
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
        if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
            return null;
        }

        File mediaStorageDir = new File(getSoundFileFolder(context));
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(TAG, "failed to create directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "AUDIO_MIXER" + prefix + timeStamp + AudioMixerParams.AUDIO_SUFFIX_AAC);

        return mediaFile;
    }

    public static String readFileFromResource(Context context, int resId) {
        InputStream is = null;
        BufferedInputStream bis = null;
        try {
            is = context.getResources().openRawResource(resId);
            bis = new BufferedInputStream(is);
            byte buffer[] = new byte[is.available()];
            is.read(buffer);
            return new String(buffer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 从流中拷贝内容并保存到文件
     *
     * @param context
     * @return
     */
    public static boolean copyFileFromResource(Context context, int resId, String filePath) {
        File file = new File(filePath);
        InputStream is = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            is = context.getResources().openRawResource(resId);
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[4096];
            int length = 0;
            while ((length = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, length);
            }
            bos.flush();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 从流中拷贝内容并保存到文件
     *
     * @param context
     * @param uri
     * @param filePath
     * @return
     */
    public static boolean copyFileFromUri(Context context, Uri uri, String filePath) {
        File file = new File(filePath);
        InputStream is = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            is = context.getContentResolver().openInputStream(uri);
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[4096];
            int length = 0;
            while ((length = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, length);
            }
            bos.flush();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 准备默认音乐文件，复制asset
     *
     * @param musicName 文件名
     */
    public static void prepareDefaultMusicFile(Context context, String musicName) {
        if (/*!SDUtils.isMounted() || */musicName == null) {
            return;
        }

        String soundFolderPath = FileUtils.getSoundFileFolder(context);
        String musicFilePath = soundFolderPath + "/" + musicName + AppConstants.MP3_FORMAT_SUFFIX;

        File musicFile = new File(musicFilePath);
        if (!musicFile.exists()) {
            copyAssetFileToSD(context.getAssets(), musicFile, musicName + AppConstants.MP3_FORMAT_SUFFIX);
        }
    }

    /**
     * 复制Asset文件到SD卡
     *
     * @param am
     * @param destinationfile
     * @param assetsfileName
     */
    public static void copyAssetFileToSD(AssetManager am, File destinationfile,
                                         String assetsfileName) {
        FileOutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            inputStream = am.open(assetsfileName);
            destinationfile.createNewFile();
            if (!destinationfile.isFile() || !destinationfile.canWrite()) {
                throw new IOException();
            }
            outputStream = new FileOutputStream(destinationfile);
            byte buf[] = new byte[2048];
            int count;
            while ((count = inputStream.read(buf)) != -1) {
                outputStream.write(buf, 0, count);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }
        }
    }

    public static boolean createFile(File file) throws IOException {
        if (!file.exists()) {
            makeDir(file.getParentFile());
        }
        return file.createNewFile();
    }

    public static void makeDir(File dir) {
        if (!dir.getParentFile().exists()) {
            makeDir(dir.getParentFile());
        }
        dir.mkdir();
    }

}
